package cn.yunyichina.provider.drug.service.impl;

import cn.yunyichina.provider.drug.config.Config;
import cn.yunyichina.provider.drug.dao.DeliveryDao;
import cn.yunyichina.provider.framework.qiniu.QiniuService;
import cn.yunyichina.provider.framework.utils.ExcelUtil;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSONArray;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.*;

/**
 * 报表服务
 * Created by Administrator on 2018/2/28.
 */
@Service
public class ReportServiceImpl {

    private Logger logger = LoggerFactory.getLogger(ReportServiceImpl.class);

    @Resource
    private Properties yaml;

    @Autowired
    private DeliveryDao deliveryDao;


    /**
     * 报表交易统计
     * yyt.drug.report.pay.list
     *
     * @param data
     * @return
     */
    public ResponseObject listReportPay(String data){
        ResponseObject response = new ResponseObject();
        try {
            logger.info("【报表服务-报表交易统计】开始, 请求="+data);

            Map<String,String> vo = JsonUtils.parseObject(data,Map.class);
            String companyCode = vo.get("company_code");
            String companyName = vo.get("company_name");
            String storeCode = vo.get("store_code");
            String storeName = vo.get("store_name");
            String beginTime = vo.get("begin_time");
            String endTime = vo.get("end_time");

            if(StringUtils.isBlank(companyCode)){
                response.setResultCodeAndMessage("23001", "company_code不能为空");
                logger.info("【报表服务-报表交易统计】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            if(StringUtils.isBlank(storeCode)){
                response.setResultCodeAndMessage("23001", "store_code不能为空");
                logger.info("【报表服务-报表交易统计】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            String pattern = "yyyy-MM-dd";
            if(StringUtils.isNotBlank(beginTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(beginTime,pattern)){
                    response.setResultCodeAndMessage("23001", "begin_time时间格式非法");
                    logger.info("【报表服务-报表交易统计】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }
            if(StringUtils.isNotBlank(endTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(endTime,pattern)){
                    response.setResultCodeAndMessage("23001", "end_time时间格式非法");
                    logger.info("【报表服务-报表交易统计】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }

            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("companyCode", companyCode);
            paramMap.put("storeCode", storeCode);
            paramMap.put("beginTime", beginTime);
            paramMap.put("endTime", endTime);

            List<Map<String, Object>> list = deliveryDao.listReportPay(paramMap);
            logger.info("【报表服务-报表交易统计】查询到" + list.size() +"条数据");

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("list",list);

            return new ResponseObject().buildResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE, JsonUtils.toJsonString(map));

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseObject().buildResultCodeAndMessage("23999", "系统异常:" + e.getMessage());
        }
    }


    /**
     * 报表交易统计订单列表导出
     * yyt.drug.report.pay.delivery.main.list.download
     *
     * @param data
     * @return
     */
    public ResponseObject downloadReportPayDeliveryMainList(String data){
        ResponseObject response = new ResponseObject();
        try {
            logger.info("【报表服务-报表交易统计订单列表导出】开始, 请求="+data);

            Map<String,String> vo = JsonUtils.parseObject(data,Map.class);
            String companyCode = vo.get("company_code");
            String companyName = vo.get("company_name");
            String storeCode = vo.get("store_code");
            String storeName = vo.get("store_name");
            String beginTime = vo.get("begin_time");
            String endTime = vo.get("end_time");

            if(StringUtils.isBlank(companyCode)){
                response.setResultCodeAndMessage("23001", "company_code不能为空");
                logger.info("【报表服务-报表交易统计订单列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            if(StringUtils.isBlank(storeCode)){
                response.setResultCodeAndMessage("23001", "store_code不能为空");
                logger.info("【报表服务-报表交易统计订单列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            String pattern = "yyyy-MM-dd";
            if(StringUtils.isNotBlank(beginTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(beginTime,pattern)){
                    response.setResultCodeAndMessage("23001", "begin_time时间格式非法");
                    logger.info("【报表服务-报表交易统计订单列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }
            if(StringUtils.isNotBlank(endTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(endTime,pattern)){
                    response.setResultCodeAndMessage("23001", "end_time时间格式非法");
                    logger.info("【报表服务-报表交易统计订单列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }

            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("companyCode", companyCode);
            paramMap.put("storeCode", storeCode);
            paramMap.put("beginTime", beginTime);
            paramMap.put("endTime", endTime);

            List<Map<String, Object>> list = deliveryDao.getPayReportDeliveryMainList(paramMap);
            logger.info("【报表服务-报表交易统计订单列表导出】查询到" + list.size() +"条数据");

            if (!CollectionUtils.isEmpty(list)) {
                JSONArray ja = JSONArray.parseArray(JsonUtils.toJsonString(list));
                Map<String, String> headMap = new LinkedHashMap<String, String>();
                headMap.put("order_no", "订单号");
                headMap.put("delivery_method", "取药方式");
                headMap.put("matched_fee", "支付金额");
                headMap.put("delivery_fee", "配送费");
                headMap.put("pay_amount", "总金额");
                headMap.put("user_name", "购买人姓名");
                headMap.put("hospital_name", "医院");
                headMap.put("store_name", "门店");
                headMap.put("mz_fee_id", "门诊流水号");
                headMap.put("pay_time", "支付时间");

                String title = "交易统计订单列表";

                String path = yaml.getProperty(Config.REPORT_PATH);
                String bucket = yaml.getProperty(Config.QINIU_BUCKET);
                String domain = yaml.getProperty(Config.QINIU_DOMAIN);

                String fileName = "交易统计订单列表" + companyCode + ".xlsx";
                String filePath = URLDecoder.decode(path + fileName, "UTF-8");
                OutputStream outXlsx = new FileOutputStream(filePath);
                Date d2 = new Date();
                ExcelUtil.exportExcelX(title, headMap, ja, null, 0, outXlsx);
                logger.info("【报表服务-报表交易统计订单列表导出】导出共" + list.size() + "条数据,执行" + (new Date().getTime() - d2.getTime()) + "ms");
                outXlsx.close();

                com.qiniu.http.Response upres = QiniuService.upload(filePath, fileName, bucket);
                if (upres.isOK() || upres.statusCode == 614) {
                    logger.info("【报表服务-报表交易统计订单列表导出】上传Excel文件成功");

                    String url = QiniuService.download(fileName, path, domain);
                    if (org.apache.commons.lang.StringUtils.isBlank(url)) {
                        logger.info("【报表服务-报表交易统计订单列表导出】获取Excel文件下载路径失败");
                        return new ResponseObject().buildResultCodeAndMessage("23003", "导出失败");
                    }

                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("url",url);

                    return new ResponseObject().buildResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE, JsonUtils.toJsonString(map));
                } else {
                    logger.info("【报表服务-报表交易统计订单列表导出】上传Excel文件失败");
                    return new ResponseObject().buildResultCodeAndMessage("23002", "导出失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseObject().buildResultCodeAndMessage("23999", "系统异常:" + e.getMessage());
        }
        return response;
    }


    /**
     * 报表交易统计订单明细列表导出
     * yyt.drug.report.pay.delivery.details.list.download
     *
     * @param data
     * @return
     */
    public ResponseObject downloadReportPayDeliveryDetailsList(String data){
        ResponseObject response = new ResponseObject();
        try {
            logger.info("【报表服务-报表交易统计订单明细列表导出】开始, 请求="+data);

            Map<String,String> vo = JsonUtils.parseObject(data,Map.class);
            String companyCode = vo.get("company_code");
            String companyName = vo.get("company_name");
            String storeCode = vo.get("store_code");
            String storeName = vo.get("store_name");
            String beginTime = vo.get("begin_time");
            String endTime = vo.get("end_time");

            if(StringUtils.isBlank(companyCode)){
                response.setResultCodeAndMessage("23001", "company_code不能为空");
                logger.info("【报表服务-报表交易统计订单明细列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            if(StringUtils.isBlank(storeCode)){
                response.setResultCodeAndMessage("23001", "store_code不能为空");
                logger.info("【报表服务-报表交易统计订单明细列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                return response;
            }

            String pattern = "yyyy-MM-dd";
            if(StringUtils.isNotBlank(beginTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(beginTime,pattern)){
                    response.setResultCodeAndMessage("23001", "begin_time时间格式非法");
                    logger.info("【报表服务-报表交易统计订单明细列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }
            if(StringUtils.isNotBlank(endTime)){
                if(!cn.yunyichina.provider.drug.utils.DateUtils.isValidDate(endTime,pattern)){
                    response.setResultCodeAndMessage("23001", "end_time时间格式非法");
                    logger.info("【报表服务-报表交易统计订单明细列表导出】结束, 返回结果=" + JsonUtils.toJsonString(response));
                    return response;
                }
            }

            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("companyCode", companyCode);
            paramMap.put("storeCode", storeCode);
            paramMap.put("beginTime", beginTime);
            paramMap.put("endTime", endTime);

            List<Map<String, Object>> list = deliveryDao.getPayReportDeliveryDetailsList(paramMap);
            logger.info("【报表服务-报表交易统计订单明细列表导出】查询到" + list.size() +"条数据");

            if (!CollectionUtils.isEmpty(list)) {
                JSONArray ja = JSONArray.parseArray(JsonUtils.toJsonString(list));
                Map<String, String> headMap = new LinkedHashMap<String, String>();
                headMap.put("order_no", "订单号");
                headMap.put("drug_code", "药店药品编码");
                headMap.put("drug_business_name", "药店药品名称");
                headMap.put("drug_spec", "药店规格");
                headMap.put("drug_qty", "销售数量");
                headMap.put("price", "药店药品单价（销售单价）");
                headMap.put("pay_time", "支付时间");

                String title = "交易统计订单明细列表";

                String path = yaml.getProperty(Config.REPORT_PATH);
                String bucket = yaml.getProperty(Config.QINIU_BUCKET);
                String domain = yaml.getProperty(Config.QINIU_DOMAIN);

                String fileName = "交易统计订单明细列表" + companyCode + ".xlsx";
                String filePath = URLDecoder.decode(path + fileName, "UTF-8");
                OutputStream outXlsx = new FileOutputStream(filePath);
                Date d2 = new Date();
                ExcelUtil.exportExcelX(title, headMap, ja, null, 0, outXlsx);
                logger.info("【报表服务-报表交易统计订单明细列表导出】导出共" + list.size() + "条数据,执行" + (new Date().getTime() - d2.getTime()) + "ms");
                outXlsx.close();

                com.qiniu.http.Response upres = QiniuService.upload(filePath, fileName, bucket);
                if (upres.isOK() || upres.statusCode == 614) {
                    logger.info("【报表服务-报表交易统计订单明细列表导出】上传Excel文件成功");

                    String url = QiniuService.download(fileName, path, domain);
                    if (org.apache.commons.lang.StringUtils.isBlank(url)) {
                        logger.info("【报表服务-报表交易统计订单明细列表导出】获取Excel文件下载路径失败");
                        return new ResponseObject().buildResultCodeAndMessage("23003", "导出失败");
                    }

                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("url",url);

                    return new ResponseObject().buildResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE, JsonUtils.toJsonString(map));
                } else {
                    logger.info("【报表服务-报表交易统计订单明细列表导出】上传Excel文件失败");
                    return new ResponseObject().buildResultCodeAndMessage("23002", "导出失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseObject().buildResultCodeAndMessage("23999", "系统异常:" + e.getMessage());
        }
        return response;
    }
}
